package com.jd.finance.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jd.finance.core.mapper.LoanApplyLogMapper;
import com.jd.finance.core.mapper.LoanApplyMapper;
import com.jd.finance.core.mapper.UserMapper;
import com.jd.finance.core.pojo.dto.GetLoanDetailInfoDTO;
import com.jd.finance.core.mapper.*;
import com.jd.finance.core.pojo.dto.LoanApplyInfoDTO;
import com.jd.finance.core.pojo.dto.NoCheckLoanDTO;
import com.jd.finance.core.pojo.entity.*;
import com.jd.finance.core.pojo.entity.LoanApply;
import com.jd.finance.core.pojo.entity.LoanApplyLog;
import com.jd.finance.core.pojo.entity.User;
import com.jd.finance.core.service.LoanApplyService;
import com.jd.finance.core.service.OpreateLogService;
import com.jd.finance.result.BaseResult;
import com.jd.finance.util.IpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 贷款申请表 服务实现类
 * </p>
 *
 * @author LiQingBo
 * @since 2022-05-25
 */
@Slf4j
@Service
public class LoanApplyServiceImpl extends ServiceImpl<LoanApplyMapper, LoanApply> implements LoanApplyService {

    @Autowired
    private AdminUtilsServiceImpl adminUtilsService;
    @Autowired
    private OpreateLogService opreateLogService;
    @Autowired
    private UserMapper userMapper;
    @Resource
    private LoanApplyMapper loanApplyMapper;
    @Resource
    private BankMapper bankMapper;
    @Resource
    private RateMapper rateMapper;
    @Resource
    private BankCardMapper bankCardMapper;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private LoanApplyLogMapper loanApplyLogMapper;



    /**
     * 获取当月贷款申请金额总数
     *
     * @param uid
     * @return
     */
    @Override
    public BaseResult getSumLoanMonth(Integer uid) {
        if (uid == null) {
            log.error("id为空!");
            return BaseResult.error().message("id为空");
        }
        Integer count = loanApplyMapper.selectMonthMoney();
        if (count == 0) {
            log.error("当月贷款申请金额总数为0!");
            return BaseResult.error().message("当月贷款申请金额总数为0");
        }

        return BaseResult.ok().data("jinemoney:", count);
    }


    /**
     * 获取未审核贷款 的 贷款申请
     * @param pageParam
     * @return
     */
    @Override
    public Page<NoCheckLoanDTO> getNoAuditLoan(Page<NoCheckLoanDTO> pageParam) {

        return loanApplyMapper.getNoAuditLoan(pageParam);


    }


    /**
     * 根据贷款申请id，获取贷款申请详情
     *
     * @param uid
     * @return
     */
    @Override
    public BaseResult getApplyLoanInfo(Integer uid, Integer loanAppId) {
        if (uid == null) {
            log.error("uid为空!");
            return BaseResult.error().message("uid为空!");
        }

        /**
         * 判断 用户 是否是 审核员 身份
         */
        if (!adminUtilsService.isAuditor(uid)) {
            log.error("用户非审核员身份!");
            return BaseResult.error().message("用户非审核员身份!");
        }

        /**
         * 响应数据
         */
        LoanApplyInfoDTO loanApplyInfoDTO = loanApplyMapper.getApplyLoanInfoFi(loanAppId);
        if (loanApplyInfoDTO == null) {
            log.error("未查询到贷款申请相关信息!");
            return BaseResult.error().message("未查询到贷款申请相关信息!");
        }
        Map<String, Object> result = new HashMap<>();
        result.put("id", loanApplyInfoDTO.getId());
        result.put("dname", loanApplyInfoDTO.getDname());
        result.put("bank", loanApplyInfoDTO.getBank());
        return BaseResult.ok().data(result);
    }


    /**
     * 获取所有第一轮通过的申请
     *
     * @param pageParam
     * @return
     */
    @Override
    public IPage<LoanApply> listPage(Page<LoanApply> pageParam) {

        QueryWrapper<LoanApply> qw = new QueryWrapper<>();
        qw.lambda().isNotNull(LoanApply::getCheckFirst);

        return loanApplyMapper.selectPage(pageParam, qw);
    }


    /**
     * 根据贷款申请id，获取贷款申请详情
     *
     * @param loanAppId
     * @return
     */
    @Override
    public BaseResult getAllApplyInfo(Integer loanAppId) {
        if (loanAppId == null) {
            log.error("loanAppid为空S");
            return BaseResult.error().message("loanAppid为空S");
        }
        QueryWrapper<LoanApply> qw = new QueryWrapper<>();
        qw.lambda().eq(LoanApply::getLoanAppId, loanAppId);

        List<LoanApply> loanApplyList = loanApplyMapper.selectList(qw);

        return BaseResult.ok().data("List", loanApplyList);
    }

    /**
     * 根据贷款申请id，修改风控状态为通过
     *
     * @param uid
     * @param loanAppId
     * @param riskId
     * @param riskName
     * @param isPass
     * @param message
     * @param isTop
     * @param topRate
     * @param agreeMoney
     * @param request
     * @return
     */
    @Transactional
    @Override
    public BaseResult passRisk(Integer uid, Integer loanAppId, Integer riskId, String riskName, Integer isPass,
                               String message, Integer isTop, BigDecimal topRate,
                               BigDecimal agreeMoney, HttpServletRequest request) {
        if (loanAppId == null || riskId == null) {
            log.error("传入id为空值C");
            return BaseResult.error().message("传入id为空值C");
        }
        if (StringUtils.isAllBlank(riskName, message)) {
            log.error("信息为空C");
            return BaseResult.error().message("信息为空C");
        }
        if (!adminUtilsService.isRisk(riskId)) {
            log.error("登录用户为非风控员C");
            return BaseResult.error().message("登录用户为非风控员C");
        }

        LoanApply loanApply = new LoanApply();
        loanApply.setLoanAppId(loanAppId);
        loanApply.setAgreeMoney(agreeMoney);
        loanApply.setCheckSecond(LocalDateTime.now());
        loanApply.setIsPassSecond(isPass);
        loanApply.setMessageSecond(message);
        loanApply.setCheckerSecondId(riskId);
        loanApply.setCheckerSecondName(riskName);
        loanApply.setTopRate(topRate);

        int i = loanApplyMapper.updateById(loanApply);

        LoanApplyLog loanApplyLog=new LoanApplyLog();
        loanApplyLog.setLoanApplyId(loanAppId.longValue());
        loanApplyLog.setLoanApplyTime(loanApply.getCreateTime());
        loanApplyLog.setCheckSecond(loanApply.getCheckSecond());
        loanApplyLog.setIsPassSecond(String.valueOf(loanApply.getIsPassSecond()));
        loanApplyLog.setMessageSecond(loanApply.getMessageSecond());
        loanApplyLog.setCheckerSecondId(riskId);
        loanApplyLog.setCheckerSecondName(riskName);
        loanApplyLog.setWorkerId(loanApply.getWorkerId());

        int num=loanApplyLogMapper.insert(loanApplyLog);
        if (num < 1) {
            log.error("添加申请日志失败!");
            return BaseResult.error().message("添加申请日志失败!");
        }

        boolean add = opreateLogService.add(uid, "修改" , "根据贷款申请id，修改风控状态为通过", IpUtil.getIpAddr(request));
        if (!add){
            log.error("操作日志添加失败");
            return BaseResult.error().message("操作日志添加失败");
        }

        return BaseResult.ok().data("fengkongzhuangtai", i);
    }




    /**
     * 根据贷款申请id，修改风控状态 未通过
     *
     * @param uid
     * @param loanAppId
     * @param riskId
     * @param riskName
     * @param isPass
     * @param message
     * @param request
     * @return
     */
    @Transactional
    @Override
    public BaseResult noPassRisk(Integer uid, Integer loanAppId, Integer riskId,
                                 String riskName, Integer isPass, String message, HttpServletRequest request) {
        if (loanAppId == null || riskId == null) {
            log.error("传入id为空值C");
            return BaseResult.error().message("传入id为空值C");
        }
        if (StringUtils.isAllBlank(riskName, message)) {
            log.error("信息为空C");
            return BaseResult.error().message("信息为空C");
        }
        if (!adminUtilsService.isRisk(riskId)) {
            log.error("登录用户为非风控员C");
            return BaseResult.error().message("登录用户为非风控员C");
        }
        LoanApply loanApply = new LoanApply();
        loanApply.setLoanAppId(loanAppId);
        loanApply.setCheckSecond(LocalDateTime.now());
        loanApply.setIsPassSecond(isPass);
        loanApply.setMessageSecond(message);
        loanApply.setCheckerSecondId(riskId);
        loanApply.setCheckerSecondName(riskName);

        int i = loanApplyMapper.updateById(loanApply);

        LoanApplyLog loanApplyLog=new LoanApplyLog();
        loanApplyLog.setLoanApplyId(loanAppId.longValue());
        loanApplyLog.setLoanApplyTime(loanApply.getCreateTime());
        loanApplyLog.setCheckSecond(loanApply.getCheckSecond());
        loanApplyLog.setIsPassSecond(String.valueOf(loanApply.getIsPassSecond()));
        loanApplyLog.setMessageSecond(loanApply.getMessageSecond());
        loanApplyLog.setCheckerSecondId(riskId);
        loanApplyLog.setCheckerSecondName(riskName);
        loanApplyLog.setWorkerId(loanApply.getWorkerId());



        int num=loanApplyLogMapper.insert(loanApplyLog);
        if (num < 1) {
            log.error("添加申请日志失败!");
            return BaseResult.error().message("添加申请日志失败!");
        }
        boolean add = opreateLogService.add(uid, "修改" , "根据贷款申请id，修改风控状态为不通过", IpUtil.getIpAddr(request));
        if (!add){
            log.error("操作日志添加失败");
            return BaseResult.error().message("操作日志添加失败");
        }


        return i >= 1 ? BaseResult.error().data("fengkongzhuangtai", 0) : BaseResult.error().message("修改失败");
    }

    /**
     * 根据 贷款申请id， 修改审核状态
     *
     * @param uid
     * @param loanAppId
     * @param loanStatus
     * @param noPassInfo
     * @param auditorId
     * @param auditorName
     * @param request
     * @return
     */
    @Transactional
    @Override
    public BaseResult updateCheckStatus(Integer uid, Integer loanAppId, String loanStatus, String noPassInfo, Integer auditorId, String auditorName, HttpServletRequest request) {
        if (StringUtils.isAllBlank(String.valueOf(uid), String.valueOf(loanAppId), loanStatus, noPassInfo, String.valueOf(auditorId), auditorName)) {
            log.error("审核信息为空!");
            return BaseResult.error().message("审核信息为空!");
        }

        /**
         * 判断 用户 是否是 审核员 身份
         */

        if (!adminUtilsService.isAuditor(uid)) {
            log.error("用户非审核员身份!");
            return BaseResult.error().message("用户非审核员身份!");
        }


        /**
         * 更新 审核状态
         */
        LoanApply loanApply = new LoanApply();
        loanApply.setCheckFirst(LocalDateTime.now());

        if (loanStatus.equals("通过")) {
            loanApply.setIsPassFirst(1);
        }

        if (loanStatus.equals("未通过")) {
            loanApply.setIsPassFirst(2);
        }

        loanApply.setMessageFirst(noPassInfo);

        loanApply.setCheckerFirstId(auditorId);
        loanApply.setCheckerFirstName(auditorName);

        QueryWrapper<LoanApply> loanApplyQueryWrapper = new QueryWrapper<>();
        loanApplyQueryWrapper.eq("loan_app_id", loanAppId);

        int count = loanApplyMapper.update(loanApply, loanApplyQueryWrapper);
        if (count < 1) {
            log.error("修改审核状态失败!");
            return BaseResult.error().message("修改审核状态失败!");
        }

        /**
         * 添加贷款申请日志
         */
        LoanApplyLog loanApplyLog=new LoanApplyLog();

        loanApplyLog.setLoanApplyId(loanAppId.longValue());
        loanApplyLog.setLoanApplyTime(loanApply.getCreateTime());
        loanApplyLog.setCheckFirst(loanApply.getCheckFirst());
        loanApplyLog.setIsPassFirst(String.valueOf(loanApply.getIsPassFirst()));
        loanApplyLog.setMessageFirst(loanApply.getMessageFirst());
        loanApplyLog.setCheckerFirstId(auditorId);
        loanApplyLog.setCheckerFirstName(auditorName);
        loanApplyLog.setWorkerId(loanApply.getWorkerId());

        int num=loanApplyLogMapper.insert(loanApplyLog);

        if (num < 1) {
            log.error("添加审核记录失败!");
            return BaseResult.error().message("添加审核记录失败!");
        }

        boolean add=opreateLogService.add(uid,"修改","根据贷款申请id,修改贷款审核状态为通过或不通过",IpUtil.getIpAddr(request));
        if (!add) {
            log.error("操作日志添加失败");
        }

        if (loanStatus.equals("通过")) {
            return BaseResult.ok().data("zhuangtai", 1);
        }
        if (loanStatus.equals("未通过")) {
            return BaseResult.ok().data("zhuangtai", 0);
        }

        return BaseResult.error().message("修改失败!");


    }

    /**
     * 贷款申请（贷款银行id，产品id，个人身份证号或企业法人身份证号，开户人（必须和企业法人身份证号一致），卡号，开用户整体负债）
     * @param bid       银行id
     * @param proId    产品id
     * @param workId
     * @param no        身份证/法人身份证号
     * @param userName  开户人
     * @param cardNum   卡号
     * @param allDebt   所有负债
     * @return          提交结果
     */
    @Override
    public BaseResult applyLoan(Integer bid, Integer proId, Integer workId, String no,
                                String userName, String loanReason, String cardNum, BigDecimal allDebt) {
        if (bid == null || proId == null || workId == null) {
            log.error("传入参数为空");
            return BaseResult.error().message("传入参数为空");
        }
        if (StringUtils.isAllBlank(userName, cardNum, no)) {
            log.error("传入参数为空");
            return BaseResult.error().message("传入参数为空");
        }
        if (allDebt == null) {
            log.error("传入参数为空");
            return BaseResult.error().message("传入参数为空");
        }
        //查询用户信息
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.lambda().eq(User::getIdNo,no);
        User user = userMapper.selectOne(qw);
        //查询银行信息
        QueryWrapper<Bank> qwb= new QueryWrapper<>();
        qwb.lambda().eq(no == null,Bank::getBid,bid);
        Bank bank = bankMapper.selectOne(qwb);
        //查询产品
        QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
        productQueryWrapper.lambda().eq(Product::getPid, proId);
        Product product = productMapper.selectOne(productQueryWrapper);
        //查询金额
        QueryWrapper<Rate> rqw = new QueryWrapper<>();
        rqw.lambda().eq(Rate::getPid,proId)
                .eq(Rate::getBid,bid);
        Rate rate = rateMapper.selectOne(rqw);
        //查询银行卡号
        QueryWrapper<BankCard> bqw = new QueryWrapper<>();
        bqw.lambda().eq(BankCard::getCardNumber,cardNum);
        BankCard bankCard = bankCardMapper.selectOne(bqw);
        // 创建贷款申请数据
        LoanApply loanApply = new LoanApply();
        loanApply.setUid(user.getUid());
        loanApply.setWorkerId(workId);
        loanApply.setProName(product.getProName());
        loanApply.setBankName(bank.getBankName());
        loanApply.setBcId(bankCard.getBcId());
        loanApply.setLoanMoney(rate.getMoney());
        loanApply.setTotalDebt(allDebt);
        loanApply.setLoanReason(loanReason);
        loanApply.setLoanApplyStatus("待审核");

        int insert = loanApplyMapper.insert(loanApply);

        //查询贷款申请
        QueryWrapper<LoanApply> lqw = new QueryWrapper<>();
        lqw.lambda().eq(LoanApply::getUid,user.getUid())
                .eq(LoanApply::getWorkerId,workId)
                .eq(LoanApply::getBankName,bank.getBankName())
                .eq(LoanApply::getProName,product.getProName())
                .eq(LoanApply::getBcId,bankCard.getBcId())
                .eq(LoanApply::getLoanMoney,rate.getMoney())
                .eq(LoanApply::getTotalDebt,allDebt)
                .eq(LoanApply::getLoanReason,loanReason)
                .eq(LoanApply::getLoanApplyStatus,"待审核");
        LoanApply loanApply1 = loanApplyMapper.selectOne(lqw);

        //添加申请贷款日志
        LoanApplyLog loanApplyLog = new LoanApplyLog();
        loanApplyLog.setLoanApplyId(Integer.toUnsignedLong(loanApply1.getLoanAppId()));
        loanApplyLog.setLoanApplyTime(loanApply.getCreateTime());
        loanApplyLog.setWorkerId(workId);

        int insert1 = loanApplyLogMapper.insert(loanApplyLog);


        if (insert >= 1 && insert1 >=1){
            return BaseResult.ok().data("tijiaoResult",1);
        }else{
            return BaseResult.ok().data("tijiaoResult",0);
        }
    }


    /**
     * 获取所有风控员信息
     *
     * @return
     */
    @Override
    public BaseResult getAllRiskManList() {
        List<User> userList = userMapper.getAllRiskManList();
        return BaseResult.ok().data("list", userList);
    }

    /**
     * 根据贷款申请id，修改申请状态及时间
     * @param uid
     * @param loanAppId
     * @param request
     * @return
     */
    @Override
    public BaseResult updateApplStatus(Integer uid, Integer loanAppId, HttpServletRequest request) {
        if(uid == null){
            log.error("uid为空");
            return BaseResult.error().message("uid为空");
        }
        if(loanAppId == null){
            log.error("loanAppId为空");
            return BaseResult.error().message("loanAppId为空");
        }

        LoanApply loanApply = new LoanApply();
        loanApply.setLoanAppId(loanAppId);
        loanApply.setLoanApplyStatus("银行已审核");
        int i = loanApplyMapper.updateById(loanApply);
        if (i<1){
            log.error("修改失败");
            return BaseResult.error().message("修改失败");
        }

        boolean add=opreateLogService.add(uid,"修改","修改申请状态",IpUtil.getIpAddr(request));
        if (!add) {
            log.error("添加操作日志失败!");
        }
        return BaseResult.ok();
    }

    /**
     * 查看已签署协议的贷款申请
     * @param officerId
     * @param page
     * @param limit
     * @return
     */
    @Override
    public BaseResult getSignedLoanApp(Integer officerId, Long page, Long limit) {
        if(officerId == null){
            log.error("officerId为空");
            return BaseResult.error().message("officerId为空");
        }
        QueryWrapper<LoanApply> qw = new QueryWrapper<>();
        qw.eq("officer_id",officerId)
                .eq("is_contract",1);
        LoanApply loanApply = new LoanApply();
        loanApply.setOfficerId(officerId);

        Page<LoanApply> page1 = new Page<>(page,limit);
        Page page2= loanApplyMapper.selectPage(page1, qw);
        return BaseResult.ok().data("list:",page2);
    }

    /**
     * 根据贷款申请id,获取贷款申请详情
     * @param loanAppId 贷款申请id
     * @param uid       信贷员id
     * @return
     */
    @Override
    public BaseResult getLoanDetailInfo(Integer loanAppId, Integer uid) {
        if (uid==null || loanAppId==null) {
            log.error("签约界面查询申请信息，信息为空!");
            return BaseResult.error().message("签约界面查询申请信息，信息为空!");
        }

        if (!adminUtilsService.isBank(uid)) {
            log.error("该用户非信贷员身份!");
            return BaseResult.error().message("该用户非信贷员身份!");
        }

        LoanApply loanApply=loanApplyMapper.selectById(loanAppId);
        if (loanApply==null) {
            log.error("贷款申请记录不存在!");
            return BaseResult.error().message("贷款申请记录不存在!");
        }

        GetLoanDetailInfoDTO getLoanDetailInfoDTO=loanApplyMapper.getLoanDetailInfo(loanAppId);

        if (getLoanDetailInfoDTO==null) {
            log.error("未查询到相关数据！");
            return BaseResult.error().message("未查询到相关数据！");
        }

        Map<String,Object> result=new HashMap<>();
        result.put("id",getLoanDetailInfoDTO.getId());
        result.put("dkjia",getLoanDetailInfoDTO.getDkjia());
        result.put("dkname",getLoanDetailInfoDTO.getDkname());
        result.put("dktime",getLoanDetailInfoDTO.getDktime());
        result.put("dkyuanyin",getLoanDetailInfoDTO.getDkyuanyin());
        result.put("lilv",getLoanDetailInfoDTO.getLilv());
        result.put("zhanghao",getLoanDetailInfoDTO.getZhanghao());
        result.put("kbank",getLoanDetailInfoDTO.getKbank());
        result.put("fangshi",getLoanDetailInfoDTO.getFangshi());
        result.put("name",getLoanDetailInfoDTO.getName());
        result.put("shenfenid",getLoanDetailInfoDTO.getShenfenid());
        result.put("iphone",getLoanDetailInfoDTO.getIphone());

        return BaseResult.ok().data(result);
    }


}
